WONT-DO: add ADR-vocabulary Status line per entry#39
Conversation
Every entry now carries `Status: Rejected | Declined | Deprecated | Superseded` matching Nygard ADR convention. The filename stays `WONT-DO.md` (echoes the Jira / Bugzilla WONTFIX slug — the recognisable lineage). Status verbs sit inside each entry for precision about reason-shape: durable architectural / values / security = Rejected; evidence- or ecosystem-gated = Declined. Preamble gains a "What the statuses mean" block with the definitions. Final tally across 36 entries: 29 Rejected, 7 Declined. IQueryable entry expanded with a scope clarification: today we ship `IObservable<'T>` only via `RxAdapter.asObservable`. Neither `IQbservable<'T>` nor `IAsyncQueryable<'T>` is exposed — both would carry the same `System.Linq.Expressions` substrate that `IQueryable` owns, so "expose async LINQ but not sync LINQ" is not a clean split. What's rejected is the pull-LINQ contract, not the expression-tree substrate. Aaron greenlit: "lets do it" + "i like your suggestions".
markdownlint-cli2 flagged the "What the statuses mean" subsection as H3 after H1 (skipped H2). Bumped to H2 so it sits at the same level as the category headers that follow the --- separator.
There was a problem hiding this comment.
Pull request overview
This PR standardizes docs/WONT-DO.md entries by adding an explicit per-entry Status: field using ADR-style vocabulary, and documents what each status means to make “won’t do” decisions more precise and scannable.
Changes:
- Add a required
Status:line to WONT-DO entries (Rejected | Declined | Deprecated | Superseded). - Add a preamble section defining each status and how it should be used.
- Expand the
IQueryableprovider entry with a scope clarification about current Rx/LINQ surfaces.
| - **Decision date** (for the record) | ||
| - **Proposal** (what was suggested) | ||
| - **Why not** (one or two sentences) | ||
| - **Revisit criteria** (what would flip the decision) |
There was a problem hiding this comment.
P2: The entry-field list says "Decision date" and "Revisit criteria", but the actual entry keys used throughout the document are "Decision:" and "Revisit when:". Please align the preamble wording with the actual field names (or rename the per-entry keys) so readers don’t have to guess which labels are canonical.
| - **Decision date** (for the record) | |
| - **Proposal** (what was suggested) | |
| - **Why not** (one or two sentences) | |
| - **Revisit criteria** (what would flip the decision) | |
| - **Decision:** (for the record) | |
| - **Proposal** (what was suggested) | |
| - **Why not** (one or two sentences) | |
| - **Revisit when:** (what would flip the decision) |
|
|
||
| - **`Rejected`** — considered and turned down for a durable | ||
| architectural, values-level, correctness, or security | ||
| reason. Revisit-when is typically "never" or "only if the |
There was a problem hiding this comment.
P2: In the status definitions, "Revisit-when" is hyphenated, but the per-entry field is consistently written as "Revisit when". For consistency (and easier searchability), standardize on one form (ideally the exact field label used in entries).
| reason. Revisit-when is typically "never" or "only if the | |
| reason. Revisit when is typically "never" or "only if the |
| is `IObservable<'T>` via `RxAdapter.asObservable` in | ||
| `src/Core/Rx.fs` — push, no expression tree. We ship neither | ||
| `IQbservable<'T>` nor `IAsyncQueryable<'T>`. Both of those carry | ||
| `System.Linq.Expressions` machinery — the same substrate | ||
| `IQueryable` owns — so "expose async LINQ but not sync LINQ" is | ||
| not a clean split: picking up the expression-tree substrate | ||
| re-opens the `IQueryable` question even if we only wanted the | ||
| async variant. What's rejected here is the pull-LINQ contract, | ||
| not the expression-tree substrate. |
There was a problem hiding this comment.
P2: The scope clarification says the only Rx-family surface shipped is IObservable<'T> via RxAdapter.asObservable, but src/Core/Rx.fs also publicly exposes RxAdapter.asObservableForCount (also returning IObservable<'T>). Consider rephrasing to refer to the RxAdapter module’s IObservable surface (or list both functions) to avoid implying there is only one entry point.
| is `IObservable<'T>` via `RxAdapter.asObservable` in | |
| `src/Core/Rx.fs` — push, no expression tree. We ship neither | |
| `IQbservable<'T>` nor `IAsyncQueryable<'T>`. Both of those carry | |
| `System.Linq.Expressions` machinery — the same substrate | |
| `IQueryable` owns — so "expose async LINQ but not sync LINQ" is | |
| not a clean split: picking up the expression-tree substrate | |
| re-opens the `IQueryable` question even if we only wanted the | |
| async variant. What's rejected here is the pull-LINQ contract, | |
| not the expression-tree substrate. | |
| is the `RxAdapter` module's `IObservable<'T>` surface in | |
| `src/Core/Rx.fs` (`RxAdapter.asObservable` and | |
| `RxAdapter.asObservableForCount`) — push, no expression tree. We | |
| ship neither `IQbservable<'T>` nor `IAsyncQueryable<'T>`. Both of | |
| those carry `System.Linq.Expressions` machinery — the same | |
| substrate `IQueryable` owns — so "expose async LINQ but not sync | |
| LINQ" is not a clean split: picking up the expression-tree | |
| substrate re-opens the `IQueryable` question even if we only | |
| wanted the async variant. What's rejected here is the pull-LINQ | |
| contract, not the expression-tree substrate. |
Summary
Status:line using Nygard ADR vocabulary:Rejected | Declined | Deprecated | Superseded.IObservable<'T>today, not IQbservable or IAsyncQueryable. The pull-LINQ contract is rejected, not the expression-tree substrate.Why
Aaron asked: "WONT-DO is that the right standard terminology other than reject?" — industry vocabulary is richer than a single slug. ADR Status (Nygard) distinguishes reason-shape (durable vs evidence-gated vs phased-out vs replaced). Jira / Bugzilla use "Won't Do" /
WONTFIXas a single bucket. The filename staysWONT-DO.md(recognisable slug) while per-entry verbs match ADR convention.Aaron greenlit: "lets do it" + "i like your suggestions".
Tally
IQueryable entry scope-clarification
Folds in Aaron's technical observation ("the async i think you need both to get the async") —
IQbservableandIAsyncQueryableboth sit onSystem.Linq.Expressions, same substrateIQueryableowns. So exposing async-LINQ-but-not-sync-LINQ isn't clean. What's rejected is the pull-LINQ contract.Test plan
python3audit script confirms 36 entries all have a Status line before Revisit-when🤖 Generated with Claude Code